package gbench.sandbox.nsql.mongo;

import org.junit.jupiter.api.Test;

import static gbench.common.matlib.MatlibCanvas.println;
import static gbench.common.matlib.algebra.lisp.IRecord.REC;
import static gbench.common.matlib.algebra.lisp.IRecord.pvtclc;
import static gbench.common.matlib.algebra.num4j.PmCm.L;
import static java.util.stream.Collectors.summarizingDouble;

import org.bson.Document;

import gbench.common.matlib.algebra.lisp.IRecord;
import gbench.common.matlib.algebra.num4j.NVec;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;

/**
 * 
 * @author Administrator
 *
 */
public class JunitMongoDB {

    @Test
    public void foo() {
        final var dd = mongodb.dframe("test", "student2");
        println(dd);
        final var dfm = dd.rowS().collect(IRecord.pvtclc(ll -> {
            return ll.size();
        }, "class"));
        println(dfm);
        mongodb.close();
    }

    @Test
    public void bar() {
        final var entries = mongodb.getCollection("test", "t_transaction");
        final var tx_rb = IRecord.rb("entitiyid,tx,createtime,entries");
        final var drcr_rb = IRecord.rb("drcr,name,amount");
        final var dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSSS");
        final var accts = "苹果，鸭梨，葡萄，西红柿，水蜜桃，西瓜".split("[，]+");
        final Function<String[], Supplier<String>> supplier = data -> {
            final var n = data.length;
            return () -> {
                final var i = (int) (Math.random() * n);
                return data[i];
            }; // supplier
        };
        final var acctget = supplier.apply(accts);
        final var n = 10000;
        for (int i = 0; i < n; i++) {
            final var timestamp = LocalDateTime.now().format(dtf);
            final var amount = Math.random() * 1000000;
            final var drcr = Math.random() > 0 ? 1 : 0;
            final var entitiyid = (int) (Math.random() * 10);
            final var b = tx_rb.get(entitiyid, timestamp, LocalDateTime.now(), L( //
                    drcr_rb.get(drcr, acctget.get(), amount), //
                    drcr_rb.get(1 - drcr, acctget.get(), amount) //
            )); //

            entries.insertOne(b.mutate2(Document::new));
            // println(d);
        }

        mongodb.close();
        println("输入数据:", n);
    }

    @Test
    public void quz() {
        final var dfm = mongodb.dframe("test", "t_transaction");
        final var dd = dfm.rowS().flatMap(e -> e.llS2("entries", IRecord::REC)) //
                .collect(pvtclc(e -> REC( //
                        "cnt", e.size(), //
                        "total", e.stream().collect(summarizingDouble(r -> r.dbl("amount"))).getSum() //
                ), "name")); //
        println(dd);
        println(dfm.row(0).json());

        final var nvec = dd.valueS().map(IRecord::REC).map(e -> e.dbl("cnt")).collect(NVec.nveclc());
        println(nvec, nvec.sum());
    }

    @Test
    public void quz1() {
        mongodb.dropCollection("t_fruit");
        final var ss = "苹果，桔子，香蕉，哈密瓜，草莓，芒果，椰子，土豆".split("[,，]+");
        final var rb = IRecord.rb("name,price,amount");
        final var n = ss.length;
        for (int k = 0; k < 10; k++)
            Stream.iterate(0, i -> i + 1).limit(n).forEach(i -> {
                final var name = ss[i];
                final var price = Math.random() * 100;
                final var amount = Math.random() * 10000;
                mongodb.getCollection("t_fruit").insertOne(rb.get(name, price, amount).mutate2(Document::new));
            });

        println("", mongodb.dframe("t_fruit"));
        mongodb.dframe("t_fruit").groupBy2(e -> e.str("name")).forEach((k, v) -> {
            println("\n", k, "\n", v);
        });

    }

    final MongoDB mongodb = new MongoDB("localhost", 40000);

}
